import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_vibrate/flutter_vibrate.dart';
import 'package:get/get.dart';
import 'package:just_audio/just_audio.dart';
import 'package:shudu/page/success_page.dart';
import 'package:shudu/utils/global.dart';
import 'package:shudu/utils/history_model.dart';
import 'package:shudu/utils/share_preference.dart';
import 'package:shudu/widget/shudu_dialog.dart';
import 'package:shudu/widget/sudoku/generator.dart';
import 'package:shudu/widget/sudoku/sudoku.dart';
import 'package:get/get.dart';

class PlayViewModel extends GetxController with WidgetsBindingObserver {
  final List<int> _originPuzzles = [];
  final puzzles = [].obs;
  final answers = [];
  final selIndex = 0.obs;
  final remindNum = 3.obs;
  final errorNum = 0.obs;
  final pause = false.obs;
  final countdownNum = 0.obs;
  Timer? _timer;
  final LEVEL level;
  final player = AudioPlayer();

  PlayViewModel(this.level);

  @override
  onInit() {
    super.onInit();
    WidgetsBinding.instance.addObserver(this);

    resetPlay();
    playMusic();
  }

  void playMusic() async {
    if (SharePreference.getMusic()) {
      player.setAsset("assets/sound/bgm.mp3");
      await player
          .setLoopMode(LoopMode.all); // Set playlist to loop (off|all|one)
      await player.play();
    }
  }

  void stopMusic() {
    if (player.playing) {
      player.stop();
    }
  }

  void pauseMusic() async {
    if (SharePreference.getMusic()) {
      await player.pause();
    }
  }

  void resumeMusic() async {
    if (SharePreference.getMusic()) {
      await player.play();
    }
  }

  void resetPlay() {
    selIndex.value = 0;
    remindNum.value = 3;
    errorNum.value = 0;
    countdownNum.value = 0;
    configGrid();
    resetTime();
  }

  void resetTime() {
    _timerCancel();
    _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
      countdownNum.value += 1;
    });
  }

  void configGrid() {
    Sudoku sudoku = Sudoku.generator(level);
    _originPuzzles.assignAll(sudoku.puzzle);
    puzzles.assignAll(sudoku.puzzle);
    answers.assignAll(sudoku.answer);
  }

  bool isOnlyReadBox(int index) => _originPuzzles[index] != -1;

  bool isCorrect(int index) {
    bool correct = false;
    if (isOnlyReadBox(index)) {
      correct = true;
    } else {
      if (puzzles[index] == answers[index]) {
        correct = true;
      } else {
        correct = false;
      }
    }
    return correct;
  }

  void operateClick(int index) {
    pause.value = false;
    resetTime();

    if (index == 1) {
    } else if (index == 2) {
      reset();
    } else {
      backPage();
    }
  }

  void fillNum(int num) {
    if (pause.value) return;

    if (isOnlyReadBox(selIndex.value)) {
      return;
    }

    puzzles[selIndex.value] = num;

    if (answers[selIndex.value] != num) {
      errorNum.value += 1;
      vibrate();

      if (errorNum.value == 3) {
        _timerCancel();

        showSDDialog("错误次数已用完", leftBtn: "放弃", rightBtn: "再试一次").then((value){
          if (value != null) {
            if (value) {
              // 放弃
              Get.back();
            } else {
              // 再试一次（广告）
              // 广告结束后 记得调用 resetPlay()
              resetPlay();
            }
          }
        });
      }
    } else {
      if (isComplete) {
        _dealSuccess();
      }
    }
  }

  void _dealSuccess() {
    _timerCancel();
    Get.to(() => SuccessPage(level, countdownNum.value),
            transition: Transition.zoom)
        ?.then((value) {
      if (value != null) {
        resetPlay();
      }
    });
    HistoryModel recordModel = HistoryModel(
        id: DateTime.now().millisecondsSinceEpoch.toString(),
        level: levelName[level],
        puzzle: _originPuzzles,
        duration: countdownNum.value,
        time: DateTime.now().millisecondsSinceEpoch);
    SharePreference.addHistoryRecord(recordModel);
  }

  void vibrate() async {
    bool isVibrate = SharePreference.getVibrate();
    if (isVibrate) return;
    bool canVibrate = await Vibrate.canVibrate;
    if (canVibrate) {
      Vibrate.vibrate();
    }
  }

  void clearItem() {
    if (pause.value) return;

    if (isOnlyReadBox(selIndex.value)) {
      return;
    }

    puzzles[selIndex.value] = -1;
  }

  void remind() {
    if (pause.value) return;

    if (remindNum.value == 0) return;
    if (isOnlyReadBox(selIndex.value)) {
      return;
    }

    remindNum.value -= 1;
    puzzles[selIndex.value] = answers[selIndex.value];
    if (isComplete) {
      _dealSuccess();
    }
  }

  void clickPause() {
    pause.value = !pause.value;
    if (pause.value) {
      _timerCancel();
    } else {
      resetTime();
    }
  }

  void _timerCancel() {
    if (_timer != null && _timer!.isActive) {
      _timer!.cancel();
      _timer = null;
    }
  }

  void reset() {
    if (pause.value) return;

    showSDDialog("放弃当前进度，重来本局").then((value) {
      if (value != null) {
        if (value) {
          countdownNum.value = 0;
          resetPlay();
        }
      }
    });
  }

  void backPage() {
    showSDDialog("放弃当前进度，返回首页").then((value) {
      if (value != null) {
        if (value) {
          Get.back();
        }
      }
    });
  }

  bool get isComplete {
    for (int i = 0; i < puzzles.length; i++) {
      if (puzzles[i] != answers[i]) {
        return false;
      }
    }
    return true;
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    switch (state) {
      case AppLifecycleState.inactive:
        break;
      case AppLifecycleState.paused:
        pauseMusic();
        break;
      case AppLifecycleState.resumed:
        resumeMusic();
        break;
      case AppLifecycleState.detached:
        stopMusic();
        break;
    }
  }

  @override
  void onClose() {
    super.onClose();
    stopMusic();
    player.dispose();
    WidgetsBinding.instance.removeObserver(this);
    _timerCancel();
  }
}
